package com.develop.GatewayService;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.develop.BeanUtils.Message;
import com.develop.BeanUtils.MsgType;
import com.develop.BeanUtils.SharedStorage;
import com.develop.GatewayService.FileSyncClient.FileSyncClient;
import com.develop.vo.AlarmMsgVo;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.EventLoop;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.ReferenceCountUtil;

/**
 * 客户端 handler
 **/

public class GatewayServiceHandler extends SimpleChannelInboundHandler<AlarmMsgVo> {
	private static final Logger LOG = LoggerFactory.getLogger(GatewayServiceHandler.class);
	private AtomicInteger reqId;
	private GatewayClient gatewayClient;
	private String host;
	private int port;
	private String user;
	private String password;

	public GatewayServiceHandler(String host, int port, String user, String password) {
		this.reqId = new AtomicInteger(0);
		this.host = host;
		this.port = port;
		this.user = user;
		this.password = password;
		this.gatewayClient = new GatewayClient(host, port, user, password);
	}

	@Override
	protected void channelRead0(ChannelHandlerContext ctx, AlarmMsgVo alarmMsgVo) throws Exception {
		LOG.info("接收到OMC消息:::" + alarmMsgVo.toString());
		try {
			if (alarmMsgVo.getMsgType() == MsgType.realTimeAlarm.getIndex()) {
				// 向业务网关同步实时告警上报数据
				SharedStorage.getBusinessGatewayClientChannel().writeAndFlush(alarmMsgVo);
			} else if (alarmMsgVo.getMsgType() == MsgType.reqSyncAlarmMsg.getIndex()) {
				// 向OMC同步消息告警请求
				ctx.channel().writeAndFlush(alarmMsgVo);
			} else if (alarmMsgVo.getMsgType() == MsgType.reqSyncAlarmFile.getIndex()) {
				// 文件方式同步告警请求
				new FileSyncClient(host, port, user, password, alarmMsgVo).run();
			} else if (alarmMsgVo.getMsgType() == MsgType.ackLoginAlarm.getIndex()) {
				if (alarmMsgVo.getBody().indexOf(";result=fail;") > 0) {
					final EventLoop eventLoop = ctx.channel().eventLoop();
					eventLoop.schedule(() -> gatewayClient.start(), 5, TimeUnit.MINUTES);
				}
			}
		} finally {
			ReferenceCountUtil.release(alarmMsgVo);
		}
	}

	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		SharedStorage.setGatewayClient(ctx.channel());
		LOG.info("OMC通道已连接！");
		StringBuffer msgBodyBuffer = new StringBuffer();
		msgBodyBuffer.append(MsgType.reqLoginAlarm + ";");
		msgBodyBuffer.append("user=" + user + ";");
		msgBodyBuffer.append("key=" + password + ";");
		msgBodyBuffer.append("type=msg");

		AlarmMsgVo alarmMsgVo = Message.generateMessage((byte) MsgType.reqLoginAlarm.getIndex(), msgBodyBuffer.toString());
		ctx.channel().writeAndFlush(alarmMsgVo);
		LOG.info("请求登录OMC...");
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
		LOG.error("异常客户端：id:{},remoteAddress:{}", ctx.channel().id(), ctx.channel().remoteAddress());
		LOG.error("出现异常:", cause);
	}

	@Override
	public void channelInactive(ChannelHandlerContext ctx) throws Exception {
		// 使用过程中断线重连
		LOG.info("OMC断线了...");
		final EventLoop eventLoop = ctx.channel().eventLoop();
		AlarmMsgVo alarmMsgVo = Message.generateMessage((byte) MsgType.closeConnAlarm.getIndex(), MsgType.closeConnAlarm + "");
		ctx.channel().writeAndFlush(alarmMsgVo);
		ctx.channel().close();
		LOG.info("发送关闭连接消息.");

		// eventLoop.schedule(() -> gatewayClient.start(), 5, TimeUnit.MINUTES);
		eventLoop.schedule(() -> gatewayClient.start(), 5, TimeUnit.SECONDS);
		ctx.fireChannelInactive();
	}

	@Override
	public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
		/** 发送心跳,保持长连接 */
		StringBuffer msgBodyBuffer = new StringBuffer();
		msgBodyBuffer.append(MsgType.reqHeartBeat + ";");
		msgBodyBuffer.append("reqId=" + this.reqId.getAndIncrement());

		AlarmMsgVo alarmMsgVo = Message.generateMessage((byte) MsgType.reqHeartBeat.getIndex(), msgBodyBuffer.toString());

		ctx.channel().writeAndFlush(alarmMsgVo);
		super.userEventTriggered(ctx, evt);
		LOG.info("向OMC发送心跳...");
	}
}
